#pragma once

#include <windows.h>

extern CInput Input;
extern u32	  hwnd;

class CWindow
{
public:
	CWindow()
	{
		m_width	   = 800;
		m_height	   = 600;
		m_fullscreen = false;

		WNDCLASSEX wc;
		ZeroMemory(&wc, sizeof(wc));
		wc.cbSize = sizeof(wc);
		wc.hInstance = GetModuleHandle(NULL);
		wc.lpszClassName = "nEngine";
		wc.lpfnWndProc = wnd_proc;
		wc.style = CS_OWNDC;
		wc.hCursor = LoadCursor(NULL,IDC_ARROW);
		wc.hbrBackground = NULL;
		RegisterClassEx(&wc);

		if(m_fullscreen)
		{
			DEVMODE dm;
			EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
			m_width = dm.dmPelsWidth;
			m_height = dm.dmPelsHeight;
		}

		m_handle = CreateWindowEx(0,"nEngine","nEngine", 
		(m_fullscreen?WS_POPUP:WS_OVERLAPPEDWINDOW)|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, 
		CW_USEDEFAULT,CW_USEDEFAULT,m_width,m_height,NULL,NULL,wc.hInstance,0);

		ASSERT(m_handle!=0,"Unable to create the window.");

		if(m_fullscreen)
			SetWindowPos((HWND)m_handle,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

		ShowCursor(1);
		ShowWindow((HWND)m_handle,SW_SHOW);
		SetFocus((HWND)m_handle);

	}
	~CWindow()
	{
		if(m_handle!=0)
		{
			CloseWindow((HWND)m_handle);
			m_handle = 0;
		}
	}
	static HWND GetHandle(){return m_handle;}
	
	static  HWND  m_handle;
			u32   m_width;
			u32   m_height;
			bool  m_fullscreen;
private:
	static LRESULT CALLBACK wnd_proc(HWND _hwnd,u32 _msg,WPARAM _wparam,LPARAM _lparam)
	{
		switch(_msg)
		{
			case WM_KEYDOWN: 
			case WM_KEYUP:
			case WM_SYSKEYDOWN:
			case WM_SYSKEYUP:
			{
				Input.SetState(_wparam,(_msg==WM_KEYDOWN)|(_msg==WM_SYSKEYDOWN));
				if((_msg==WM_SYSKEYDOWN)&&(_wparam==13))
				{
					// Alt + Enter
				}
			}
			break;
			case WM_LBUTTONDOWN:
			case WM_LBUTTONUP:
			{
				Input.SetState(K_MOUSE_L,(_msg==WM_LBUTTONDOWN));
			}
			break;
			case WM_RBUTTONDOWN:
			case WM_RBUTTONUP:
			{
				Input.SetState(K_MOUSE_R,(_msg==WM_RBUTTONDOWN));
			}
			break;
			case WM_MBUTTONDOWN:
			case WM_MBUTTONUP: 
			{
				Input.SetState(K_MOUSE_M,(_msg==WM_MBUTTONDOWN));
			}
			break;
			case WM_MOUSEWHEEL:
			{
				Input.SetState(K_MOUSE_WU, short(_wparam>>16)>0);
				Input.SetState(K_MOUSE_WD, short(_wparam>>16)<0);
			}
			break;
			case WM_MOUSEMOVE:
			{
				RECT rc;
				POINT p;
				GetWindowRect(CWindow::GetHandle(),&rc);
				GetCursorPos(&p);
				Input.SetRC(rc);
				Input.SetPos(p);
			}
			break;
			case WM_ACTIVATEAPP:
			{
				Input.Reset();
			}
			break;
			case WM_SYSCOMMAND:	
			{
				switch (_wparam)		
				{
				case SC_SCREENSAVE:	
				case SC_MONITORPOWER:
					return 0;
				}
			}
			break;
			case WM_CLOSE:
			case WM_DESTROY:
			{
				PostQuitMessage(0);
				return 0;
			}
			break;
		}
		return DefWindowProc(_hwnd,_msg,_wparam,_lparam);
	}
};

HWND CWindow::m_handle = 0;